package craky.keeper.skin;

import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.sun.awt.AWTUtilities;

import craky.componentc.CRootPaneUI;
import craky.componentc.JCMessageBox;
import craky.componentc.JCSlider;
import craky.componentc.JCToggleButton;
import craky.keeper.KeeperApp;
import craky.keeper.KeeperConst;
import craky.keeper.util.KeeperUtil;
import craky.util.UIUtil;

public class SkinMgr implements MouseListener, ChangeListener, ActionListener,
		PopupMenuListener {
	private KeeperApp keeper;
	private SkinMenu menu;
	private File currentDir;

	public SkinMgr(KeeperApp keeper, SkinMenu menu) {
		this.keeper = keeper;
		this.menu = menu;
	}

	public void removeSkin(Skin skin, boolean showConfirm) {
		if (skin != null) {
			if (showConfirm) {
				this.menu.showPane(false, skin);
			} else {
				String name = skin.getName();
				String current = this.keeper.getCurrentSkin().getName();
				this.keeper.getAllSkins().remove(name.toUpperCase());
				this.menu.resetSkins();
				this.keeper.changeSkin(this.keeper.getSkin(current), true);
				KeeperUtil.deleteDirectory(new File(KeeperConst.SKIN_DIR
						+ KeeperConst.FILE_SEP + name));
			}
		}
	}

	public void addSkin() {
		this.menu.getModel().setSelected(false);
		this.menu.setPopupMenuVisible(false);
		JFileChooser chooser = new JFileChooser();
		String filterDes = "图像文件(*.bmp;*.jpg;*.jpeg;*.png)";
		FileNameExtensionFilter filter = new FileNameExtensionFilter(filterDes,
				new String[] { "bmp", "jpg", "jpeg", "png" });
		chooser.setApproveButtonMnemonic('O');
		chooser.setApproveButtonText("打开(O)");
		chooser.setCurrentDirectory(this.currentDir);
		chooser.setFileFilter(filter);
		chooser.setAcceptAllFileFilterUsed(false);
		int ret = chooser.showOpenDialog(this.keeper.getMainFrame());

		if (ret == 0) {
			File file = chooser.getSelectedFile();
			this.currentDir = file.getParentFile();
			String name = file.getName();
			int lastDotIndex = name.lastIndexOf('.');
			name = lastDotIndex > 0 ? name.substring(0, lastDotIndex) : name;

			if (this.keeper.getSkin(name) != null) {
				String title = "添加皮肤";
				String message = "皮肤" + name + "”已经存在，是否替换";
				JCMessageBox confirm = JCMessageBox.createQuestionMessageBox(
						this.keeper.getMainFrame(), title, message);

				if (confirm.open() != 4) {
					return;
				}
			}

			try {
				BufferedImage image = ImageIO.read(file);
				BufferedImage blurImage = UIUtil.createEdgeBlurryImage(image,
						30, CRootPaneUI.BLUR_FILTER, null);
				BufferedImage previewImage = createPreviewImage(image);
				Skin skin = new Skin(name);
				String skinDirPath = KeeperConst.SKIN_DIR
						+ KeeperConst.FILE_SEP + name;
				File skinDir = new File(skinDirPath);

				if (!skinDir.exists()) {
					skinDir.mkdirs();
				}

				ImageIO.write(image, "png", new File(skinDirPath
						+ KeeperConst.FILE_SEP + "normal.png"));
				ImageIO.write(blurImage, "png", new File(skinDirPath
						+ KeeperConst.FILE_SEP + "blur.png"));
				ImageIO.write(previewImage, "png", new File(skinDirPath
						+ KeeperConst.FILE_SEP + "preview.png"));
				this.keeper.getAllSkins().put(skin.getName().toUpperCase(),
						skin);
				this.menu.resetSkins();
				this.keeper.changeSkin(skin, true);
				image = null;
				blurImage = null;
				previewImage = null;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	private BufferedImage createPreviewImage(BufferedImage image) {
		BufferedImage previewImage = UIUtil.getGraphicsConfiguration(null)
				.createCompatibleImage(30, 41, 3);
		Graphics2D g2d = previewImage.createGraphics();
		g2d.drawImage(image, 0, 0, previewImage.getWidth(),
				previewImage.getHeight(), null);
		g2d.dispose();
		return previewImage;
	}

	public boolean needChange(Point point, Container source) {
		int x = point.x + source.getX();
		int y = point.y + source.getY();

		while (!(source instanceof SkinUnit)) {
			source = source.getParent();
			x += source.getX();
			y += source.getY();
		}

		return !this.menu.getSkinListBounds().contains(x, y);
	}

	public void mouseReleased(MouseEvent e) {
		Object source = e.getSource();

		if ((source instanceof JComponent)) {
			JComponent c = (JComponent) source;
			Object eventKey = c.getClientProperty("EventKey");

			if (eventKey.equals("SkinAlphaChanged")) {
				this.keeper.getConfig().savePropertie(
						"Skin_Alpha",
						String.valueOf(this.keeper.getMainFrame()
								.getImageAlpha()));
			} else if (eventKey.equals("WinAlphaChanged")) {
				this.keeper.getConfig().savePropertie(
						"Win_Alpha",
						String.valueOf(AWTUtilities
								.getWindowOpacity(this.keeper.getMainFrame())));
			}
		}
	}

	public void mouseEntered(MouseEvent e) {
		Object source = e.getSource();

		if ((source instanceof JComponent)) {
			JComponent c = (JComponent) source;
			Object eventKey = c.getClientProperty("EventKey");

			if (eventKey.equals("SkinModePreview")) {
				this.menu.modePreview((Image) c.getClientProperty("BigImage"),
						false);
			}
		}
	}

	public void mouseExited(MouseEvent e) {
		Object source = e.getSource();

		if ((source instanceof JComponent)) {
			JComponent c = (JComponent) source;
			Object eventKey = c.getClientProperty("EventKey");

			if (eventKey.equals("SkinModePreview")) {
				this.menu.modePreview((Image) c.getClientProperty("BigImage"),
						true);
			}
		}
	}

	public void stateChanged(ChangeEvent e) {
		Object source = e.getSource();

		if ((source instanceof JComponent)) {
			JComponent c = (JComponent) source;
			Object eventKey = c.getClientProperty("EventKey");

			if (eventKey.equals("SkinAlphaChanged")) {
				this.keeper.getMainFrame().setImageAlpha(
						((JCSlider) c).getValue() / 100.0F);
			} else if (eventKey.equals("WinAlphaChanged")) {
				AWTUtilities.setWindowOpacity(this.keeper.getMainFrame(),
						((JCSlider) c).getValue() / 100.0F);
			}
		}
	}

	public void actionPerformed(ActionEvent e) {
		Object source = e.getSource();

		if ((source instanceof JComponent)) {
			JComponent c = (JComponent) source;
			Object eventKey = c.getClientProperty("EventKey");

			if ((eventKey.equals("SkinModePreview"))
					&& (((JCToggleButton) c).isSelected())) {
				this.keeper.getMainFrame().setImageDisplayMode(
						(CRootPaneUI.ImageDisplayMode) c
								.getClientProperty("SkinModeValue"));
				this.keeper.getConfig().savePropertie(
						"Skin_Mode",
						String.valueOf(this.keeper.getMainFrame()
								.getImageDisplayMode()));
			} else if (eventKey.equals("DelSkinOK")) {
				removeSkin(((DeleteConfirmPane) c.getParent()).getSkin(), false);
				this.menu.showPane(true, null);
			} else if (eventKey.equals("DelSkinCancel")) {
				this.menu.showPane(true, null);
			}
		}
	}

	public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
		this.menu.showPane(true, null);
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
	}

	public void popupMenuCanceled(PopupMenuEvent e) {
	}
}